﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Biomedica.Graphics
{
   

    public class Vector3
    {
        public float X { set; get; }
        public float Y {set;get;}
        public float Z{set;get;}
        public Vector3 Theta { set; get; }

        public Vector3(float x, float y, float z)
        {
            X = x;
            Y = y;
            Z = z;
           
                float thetaX = (float)System.Math.Acos(X / Resultant());
                float thetaY = (float)System.Math.Acos(Y / Resultant());
                float thetaZ = (float)System.Math.Acos(Z / Resultant());
               // if (!float.IsNaN(thetaX) && !float.IsNaN(thetaY) && !float.IsNaN(thetaZ))
             //       Theta = new Vector3(thetaX, thetaY, thetaZ);
             //   else Theta = Vector3.Zero;
           
        }

        public static Vector3 operator +(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);

        }
        public static Vector3 operator -(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
        }
        public static Vector3 operator *(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z);
        }
        public static Vector3 operator /(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.X / v2.X, v1.Y / v2.Y, v1.Z / v2.Z);
        }
        public static Vector3 operator /(Vector3 v, float d)
        {
            return new Vector3(v.X / d, v.Y / d, v.Z / d);
        }
        public static Boolean operator &(Vector3 v1, Vector3 v2)
        {
            return (v1.X == v2.X) & (v1.Y == v2.Y)&( v1.Z== v2.Z);
        }
        public static Boolean operator |(Vector3 v1, Vector3 v2)
        {
            return (v1.X == v2.X) | (v1.Y == v2.Y) | (v1.Z == v2.Z);
        }
        public double Distance(Vector3 v1, Vector3 v2)
        {
            return System.Math.Sqrt(((v1.X - v2.X) * (v1.X - v2.X)) + ((v1.Y - v2.Y) * (v1.Y- v2.Y)) + ((v1.Z - v2.Z) * (v1.Z - v2.Z)));
        }
        public static Vector3 Zero
        {
            get { return new Vector3(0, 0, 0); }
        }
        public static Vector3 One
        {
            get { return new Vector3(1, 1, 1); }
        }
        public double Resultant()
        {
            return System.Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
        }
        public double Resultant(Vector3 v)
        {
            float dx=X-v.X;
            float dy=Y-v.Y;
            float dz=Z-v.Z;
            return System.Math.Sqrt((dx*dx) + (dy *dy) + (dz*dz));
        }


        internal Vector3 Distance(Vector3 v)
        {
            float dx = X - v.X;
            float dy = Y - v.Y;
            float dz = Z - v.Z;
            return new Vector3(dx, dy, dz);
        }

        public bool HasValue { get { return X != null && Y != null && Z != null; } }
    }
   
    
    
    public class TimeVectored
    {
        public float X { set; get; }
        public float Y { set; get; }
        public float Z { set; get; }
        public float Time { set; get; }
 
        public TimeVectored(float x, float y, float z, float t)
        {
            X = x;
            Y = y;
            Z = z;
            Time = t;
        }

        public static TimeVectored operator +(TimeVectored v1, TimeVectored v2)
        {
            return new TimeVectored(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, v1.Time);

        }
        public static TimeVectored operator -(TimeVectored v1, TimeVectored v2)
        {
            return new TimeVectored(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, v1.Time);
        }
        public static TimeVectored operator *(TimeVectored v1, TimeVectored v2)
        {
            return new TimeVectored(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, v1.Time);
        }
        public static TimeVectored operator /(TimeVectored v1, TimeVectored v2)
        {
            return new TimeVectored(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, v1.Time);
        }
        public static Boolean operator &(TimeVectored v1, TimeVectored v2)
        {
            return (v1.X == v2.X) & (v2.Y == v2.Y) & (v1.Z == v2.Z) & (v1.Time == v2.Time);
        }
        public static Boolean operator |(TimeVectored v1, TimeVectored v2)
        {
            return (v1.X == v2.X) | (v2.Y == v2.Y) | (v1.Z == v2.Z) | (v1.Time == v2.Time);
        }
        public static TimeVectored Zero
        {
            get { return new TimeVectored(0, 0, 0, 0); }
        }
        public static TimeVectored One
        {
            get { return new TimeVectored(1, 1, 1, 1); }
        }
      
    }
}
